package ckw.database;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import ckw.database.resultPattern.*;
import ckw.util.HibernateUtil;


import core.exceptions.ConnectionBetweenObjectsException;
import core.exceptions.DatabaseObjectNotFoundException;
import core.exceptions.NoConnectionBetweenObjectsException;
import core.exceptions.OKWWithElectionException;
import core.modules.LoggerModule;
import core.modules.configuration.ConfigurationManager;
import core.modules.database.corebase.AdministratorTokenCore;
import core.modules.database.corebase.ElectionCore;
import core.modules.database.corebase.ElectionData;
import core.modules.database.corebase.OKWElectionResultCore;
import core.modules.database.corebase.OKWMemberCore;
import core.modules.database.corebase.SummaryPackageCore;
import core.modules.database.corebase.VoteCore;
import core.modules.database.corebase.VoterCore;
import core.modules.database.corebase.VotesPackageCore;
import core.modules.database.corebase.VotingCardCore;
import core.modules.database.corebase.VotingSubcardCore;
import core.modules.database.corebase.VotingSubcardOptionCore;

public class DatabaseManager {

	private static DatabaseManager instance;
	private static LoggerModule logger = null;

	private DatabaseManager() {
		HibernateUtil.getSessionFactory().getCurrentSession();
		try {
	    	logger = new LoggerModule("ckwDatabase.log", null);
	    } catch (IOException e) {
	    	e.printStackTrace();
			throw new RuntimeException("Problems with creating the log files");
	    }
		logger.getLoggerInstance().log(Level.FINE, "Start bazy danych");
	}

	public static DatabaseManager getInstance() {
		if (instance == null) {
			synchronized (DatabaseManager.class) {
				if (instance == null)
					instance = new DatabaseManager();
			}
		}
		return instance;
	}

	public void closeDatabaseSession() {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		HibernateUtil.getSessionFactory().close();
	}

	public Long save(Object obj) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		Long id = (Long) session.save(obj);

		session.getTransaction().commit();
		logger.getLoggerInstance().log(Level.FINE, "Zapis obiektu klasy "+obj.getClass().getSimpleName());
		return id;
	}

	public void update(Object obj) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		session.update(obj);

		session.getTransaction().commit();
		logger.getLoggerInstance().log(Level.FINE, "Update obiektu klasy "+obj.getClass().getSimpleName());
	}

	public <T> T get(Class<T> obj, Long id) { // przykładowe wywołanie:
												// get(OKW.class, okw.getId());
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		@SuppressWarnings("unchecked")
		T object = (T) session.get(obj.getName(), id);

		session.getTransaction().commit();
		logger.getLoggerInstance().log(Level.FINE, "Pobranie obiektu klasy "+object.getClass().getSimpleName());
		return object;
	}

	public <T> List<T> getAll(Class<T> obj) { // przykładowe wywołanie:
												// getAll(OKW.class);
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		String querystring = "from " + obj.getSimpleName();
		Query query = session.createQuery(querystring);
		@SuppressWarnings("unchecked")
		List<T> list = query.list();

		session.getTransaction().commit();
		logger.getLoggerInstance().log(Level.FINE, "Pobranie wszystkich obiektów klasy "+list.getClass().getSimpleName());
		return list;
	}

	public void saveAdministratorToken(String value, OKWMember okwMember,
			Election election) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		AdministratorToken administratorToken = new AdministratorToken(value);
		administratorToken.addToOkwmember(okwMember);
		administratorToken.addToElection(election);
		session.save(administratorToken);

		session.getTransaction().commit();
		logger.getLoggerInstance().log(Level.FINE, "Zapis obiektu klasy "+administratorToken.getClass().getSimpleName());
	}

	public void changeOKWElectionStatus(String electionName,
			String okwIdentifiactionField, int status) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		Election election = (Election) session.createCriteria(Election.class)
				.add(Restrictions.like("name", electionName)).uniqueResult();

		OKW okw = (OKW) session
				.createCriteria(OKW.class)
				.add(Restrictions.like("identificationField",
						okwIdentifiactionField)).uniqueResult();

		OKW_Election okw_Election = (OKW_Election) session
				.createCriteria(OKW_Election.class)
				.add(Restrictions.like("election", election))
				.add(Restrictions.like("okw", okw)).uniqueResult();

		okw_Election.setStatus(status);
		session.update(okw_Election);

		session.getTransaction().commit();
		logger.getLoggerInstance().log(Level.FINE, "Zmiana statusu OKW: {0} i Election: {1} na Status: {2}",new Object[] {okwIdentifiactionField, electionName, status});
	}

	public void addOKWToElection(OKW okw, Election election) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		OKW_Election okwElection = new OKW_Election(okw, election);
		session.save(okwElection);

		session.getTransaction().commit();
		logger.getLoggerInstance().log(Level.FINE, "Dodanie OKW: {0} do Election: {1}",new Object[] {okw.getIdentificationField(), election.getName()});
	}

	public void addOKWMemberToOKW(OKWMember okwMember, OKW okw)
			throws ConnectionBetweenObjectsException {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		OKWMember tmpOkwMember = (OKWMember) session
				.createCriteria(OKWMember.class).createAlias("okws", "o")
				.add(Restrictions.like("o.id", okw.getId())).uniqueResult();

		if (tmpOkwMember != null) {
			session.getTransaction().rollback();
			throw new ConnectionBetweenObjectsException();
		}

		okw.addToOkwMember(okwMember);
		session.update(okw);
		session.update(okwMember);

		session.getTransaction().commit();
		logger.getLoggerInstance().log(Level.FINE, "Dodanie OKWMembera: {0} do OKW: {1}",new Object[] {okwMember.getIdentificationField(), okw.getIdentificationField()});
	}

	public void removeOKWMemberFromOKW(OKWMember okwMember, OKW okw)
			throws NoConnectionBetweenObjectsException {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		okw = (OKW) session.get(OKW.class, okw.getId());
		okwMember = (OKWMember) session.get(OKWMember.class, okwMember.getId());

		OKWMember tmpOkwMember = (OKWMember) session
				.createCriteria(OKWMember.class).createAlias("okws", "o")
				.add(Restrictions.like("o.id", okw.getId())).uniqueResult();

		if (tmpOkwMember == null) {
			session.getTransaction().rollback();
			throw new NoConnectionBetweenObjectsException();
		}

		okw.removeFromOkwMember(okwMember);
		session.update(okw);
		session.update(okwMember);

		session.getTransaction().commit();
		logger.getLoggerInstance().log(Level.FINE, "Usunięcie OKWMembera: {0} z OKW: {1}",new Object[] {okwMember.getIdentificationField(), okw.getIdentificationField()});
	}

	public void addConfigurationToOKW(Configuration configuration, OKW okw) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		Configuration conf = okw.getConfiguration();
		if (conf != null)
			session.delete(conf);
		okw.setConfiguration(configuration);
		session.update(okw);

		session.getTransaction().commit();
		logger.getLoggerInstance().log(Level.FINE, "Dodanie pliku konfiguracyjnego do OKW: "+okw.getIdentificationField());
	}

	public void addNonresidentVoterToElection(Voter voter, Election election) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		NonresidentVoter nonresidentVoter = new NonresidentVoter(voter,
				election);
		session.save(nonresidentVoter);

		session.getTransaction().commit();
		logger.getLoggerInstance().log(Level.FINE, "Dodanie nonresidentVoter do Election: ", election.getName());
	}

	public void addVoterToVotersList(Voter voter, VotersList votersList)
			throws ConnectionBetweenObjectsException {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		VotersList tmpVotersList = (VotersList) session
				.createCriteria(VotersList.class).createAlias("voters", "v")
				.add(Restrictions.like("v.id", voter.getId()))
				.add(Restrictions.like("id", votersList.getId()))
				.uniqueResult();

		if (tmpVotersList != null) {
			session.getTransaction().rollback();
			throw new ConnectionBetweenObjectsException();
		}

		votersList.addToVoter(voter);
		session.update(votersList);
		session.update(voter);

		session.getTransaction().commit();
	}

	public void removeVoterFromVotersList(Voter voter, VotersList votersList)
			throws NoConnectionBetweenObjectsException {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		voter = (Voter) session.get(Voter.class, voter.getId());
		votersList = (VotersList) session.get(VotersList.class,
				votersList.getId());

		VotersList tmpVotersList = (VotersList) session
				.createCriteria(VotersList.class).createAlias("voters", "v")
				.add(Restrictions.like("v.id", voter.getId()))
				.add(Restrictions.like("id", votersList.getId()))
				.uniqueResult();

		if (tmpVotersList == null) {
			session.getTransaction().rollback();
			throw new NoConnectionBetweenObjectsException();
		}

		votersList.removeFromVoter(voter);
		session.update(votersList);
		session.update(voter);

		session.getTransaction().commit();
	}

	public void addVoterListToElection(VotersList votersList, Election election) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		election.addToVotersList(votersList);
		session.update(election);
		session.update(votersList);

		session.getTransaction().commit();
	}

	public void addVoteToVotingSubcardOption(Vote vote,
			VotingSubcardOption votingSubcardOption) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		votingSubcardOption.addToVote(vote);
		session.update(votingSubcardOption);
		session.update(vote);

		session.getTransaction().commit();
	}

	public int getVotesForVotingSubcardOption(
			VotingSubcardOption votingSubcardOption) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		VotingSubcardOption tmpVotingSubcardOption = (VotingSubcardOption) session
				.get(VotingSubcardOption.class, votingSubcardOption.getId());
		Set<Vote> votes = tmpVotingSubcardOption.getVotes();

		session.getTransaction().commit();
		return votes.size();
	}

	public void removeVoterListFromElection(VotersList votersList,
			Election election) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		election.removeFromVotersList(votersList);
		session.update(election);
		session.update(votersList);

		session.getTransaction().commit();
	}

	public void setIsSendToFalse(Election election) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		Election electionTmp = (Election) session.get(Election.class,
				election.getId());
		for (OKW_Election okw_election : electionTmp.getOkw_elections()) {
			okw_election.setIsSend(false);
			session.update(okw_election);
		}

		session.getTransaction().commit();
	}

	public void setIsSend(Election election, OKW okw, Boolean isSend) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		@SuppressWarnings("unchecked")
		List<OKW_Election> okw_elections = session
				.createCriteria(OKW_Election.class)
				.add(Restrictions.like("okw", okw))
				.add(Restrictions.like("election", election)).list();
		for (OKW_Election okw_election : okw_elections) {
			okw_election.setIsSend(isSend);
			session.saveOrUpdate(okw_election);
		}

		session.getTransaction().commit();
	}

	public void setIsSend(String electionName, OKW okw, Boolean isSend) {
		Election election = getElection(electionName);
		if (election != null)
			setIsSend(election, okw, isSend);
	}

	public Election getElection(String electionName) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		Election election = (Election) session.createCriteria(Election.class)
				.add(Restrictions.like("name", electionName)).uniqueResult();

		session.getTransaction().commit();

		return election;
	}

	public OKW getOKW(String identificationField) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		OKW okw = (OKW) session
				.createCriteria(OKW.class)
				.add(Restrictions.like("identificationField",
						identificationField)).uniqueResult();

		session.getTransaction().commit();

		return okw;
	}

	public void setNonresidentVoterAsVoted(String identificationField,
			String electionName, int voterStatus, String okwIdentificationField) {
		Election election = getElection(electionName);
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		Voter voter = (Voter) session
				.createCriteria(Voter.class)
				.add(Restrictions.like("identificationField",
						identificationField)).uniqueResult();
		try {
			NonresidentVoter nonresidentVoter;
			try {
				nonresidentVoter = (NonresidentVoter) session
						.createCriteria(NonresidentVoter.class)
						.add(Restrictions.like("voter", voter))
						.add(Restrictions.like("election", election))
						.uniqueResult();
				nonresidentVoter.setVoterStatus(voterStatus);
				nonresidentVoter
						.setOkwIdentificationField(okwIdentificationField);
				session.saveOrUpdate(nonresidentVoter);

				session.getTransaction().commit();
				
				logger.getLoggerInstance().log(Level.FINE, "Zweryfikowanie głosującego niezamieszkałego Voter: {0} w wyborach Election: {1}", new Object[] {identificationField, electionName});
			} catch (HibernateException e) {
				session.getTransaction().rollback();
				e.printStackTrace();
			}
		} catch (HibernateException e) {
			session.getTransaction().rollback();
			e.printStackTrace();
		}
	}

	public int hasNonresidentVoterVoted(String identificationField,
			String electionName) throws DatabaseObjectNotFoundException {
		Election election = getElection(electionName);
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		Voter voter = (Voter) session
				.createCriteria(Voter.class)
				.add(Restrictions.like("identificationField",
						identificationField)).uniqueResult();
		NonresidentVoter nonresidentVoter;
		nonresidentVoter = (NonresidentVoter) session
				.createCriteria(NonresidentVoter.class)
				.add(Restrictions.like("voter", voter))
				.add(Restrictions.like("election", election)).uniqueResult();
		session.getTransaction().commit();
		if (nonresidentVoter != null)
			return nonresidentVoter.getVoterStatus();
		else
			throw new DatabaseObjectNotFoundException();
	}

	public Voter getNonresidentVoter(String identificationField,
			String electionName) {
		Election election = getElection(electionName);
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		Voter voter = (Voter) session
				.createCriteria(Voter.class)
				.add(Restrictions.like("identificationField",
						identificationField)).uniqueResult();
		if (voter != null) {
			NonresidentVoter nonresidentVoter = (NonresidentVoter) session
					.createCriteria(NonresidentVoter.class)
					.add(Restrictions.like("voter", voter))
					.add(Restrictions.like("election", election))
					.uniqueResult();
			session.getTransaction().commit();
			if (nonresidentVoter != null)
				return voter;
			else
				return null;
		}
		session.getTransaction().commit();
		return null;
	}

	public boolean hasMassage(String senderIdentificationField,
			int messageNumber, String electionName) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		Message message = (Message) session
				.createCriteria(Message.class)
				.add(Restrictions.like("senderIdentificationField",
						senderIdentificationField))
				.add(Restrictions.like("messageNumber", messageNumber))
				.add(Restrictions.like("electionName", electionName))
				.uniqueResult();

		session.getTransaction().commit();

		if (message != null)
			return true;
		return false;
	}

	public void saveState(State state) {
		deleteTable(State.class);
		save(state);
	}

	public State getState() {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		State state = (State) session.createCriteria(State.class)
				.uniqueResult();
		session.getTransaction().commit();

		return state;
	}

	public <T> void deleteTable(Class<T> obj) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		String querystring = "delete from " + obj.getName();
		Query query = session.createQuery(querystring);
		query.executeUpdate();

		session.getTransaction().commit();
	}

	public Election getElectionByToken(String token,
			String okwIdentifcationField) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		AdministratorToken administratorToken = (AdministratorToken) session
				.createCriteria(AdministratorToken.class)
				.add(Restrictions.like("value", token)).uniqueResult();

		if (administratorToken != null) {
			Election election = administratorToken.getElection();
			election = (Election) session.get(Election.class, election.getId());
			OKW okw = (OKW) session
					.createCriteria(OKW.class)
					.add(Restrictions.like("identificationField",
							okwIdentifcationField)).uniqueResult();

			if (okw == null) {
				session.getTransaction().commit();
				return null;
			}

			OKW_Election okw_Election = (OKW_Election) session
					.createCriteria(OKW_Election.class)
					.add(Restrictions.like("okw", okw))
					.add(Restrictions.like("election", election))
					.uniqueResult();
			session.getTransaction().commit();
			if (okw_Election == null)
				return null;
			else
				return election;
		} else {
			session.getTransaction().commit();
			return null;
		}
	}

	public ArrayList<OKWMemberCore> getOKWMemberCore(OKW okw, Election election) {
		ArrayList<OKWMemberCore> okwMemberCores = new ArrayList<OKWMemberCore>();
		AdministratorTokenCore administratorTokenCore;
		Set<OKWMember> okwMembers = okw.getOkwMembers();
		for (OKWMember okwMember : okwMembers) {
			OKWMember tmpOKWMember = get(OKWMember.class, okwMember.getId());
			Set<AdministratorToken> administratorTokens = tmpOKWMember
					.getAdministratorTokens();
			OKWMemberCore okwMemberCore = new OKWMemberCore(
					okwMember.getName(), okwMember.getSurname(),
					okwMember.getAddress(), okwMember.getIdentificationField());
			for (AdministratorToken administratorToken : administratorTokens) {
				if ((administratorToken.getElection().getId()
						.compareTo(election.getId())) == 0) {
					administratorTokenCore = new AdministratorTokenCore(
							administratorToken.getValue());
					okwMemberCore.getAdministratorTokens().add(
							administratorTokenCore);
				}
			}
			if (!okwMemberCore.getAdministratorTokens().isEmpty())
				okwMemberCores.add(okwMemberCore);
		}
		return okwMemberCores;
	}

	public ArrayList<VotingCardCore> getVotingCardCore(Election election) {
		ArrayList<VotingCardCore> votingCardCores = new ArrayList<VotingCardCore>();

		for (VotingCard votingCard : election.getVotingCards()) {
			VotingCardCore votingCardCore = new VotingCardCore(
					votingCard.getName(), votingCard.getDescription());
			for (VotingSubcard votingSubcard : votingCard.getVotingSubcards()) {
				VotingSubcardCore votingSubcardCore = new VotingSubcardCore(
						votingSubcard.getName(),
						votingSubcard.getDescription(),
						votingSubcard.getAllowedChecks());
				for (VotingSubcardOption votingSubcardOption : votingSubcard
						.getVotingSubcardOptions()) {
					VotingSubcardOptionCore votingSubcardOptionCore = new VotingSubcardOptionCore(
							votingSubcardOption.getName(),
							votingSubcardOption.getId());
					votingSubcardCore.getVotingSubcardOptions().add(
							votingSubcardOptionCore);
				}
				votingCardCore.getVotingSubcards().add(votingSubcardCore);
			}
			votingCardCores.add(votingCardCore);
		}
		return votingCardCores;
	}

	public boolean isNonresidentVoter(Election election, Voter voter) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		@SuppressWarnings("unchecked")
		List<NonresidentVoter> nonresidentVoters = session
				.createCriteria(NonresidentVoter.class)
				.add(Restrictions.like("voter", voter))
				.add(Restrictions.like("election", election)).list();

		session.getTransaction().commit();
		if (nonresidentVoters.isEmpty())
			return false;
		return true;
	}

	public ArrayList<Voter> getVoters(Election election) { // TODO: kiedyś poprawić sprawdzanie czy już jest (Mapa)
		ArrayList<Voter> voters = new ArrayList<Voter>();
		Map<String, Voter> tmpVotersMap = new HashMap<>();

		for (VotersList votersList : election.getVotersLists()) {
			for (Voter voter : votersList.getVoters()) {
				if (!isNonresidentVoter(election, voter) && !tmpVotersMap.containsKey(voter.getIdentificationField())) {
					tmpVotersMap.put(voter.getIdentificationField(), voter);
					voters.add(voter);
				}
			}
		}

		return voters;
		
	}

	public ArrayList<VoterCore> getVoterCores(OKW okw, ArrayList<Voter> voters) {
		ArrayList<VoterCore> voterCores = new ArrayList<VoterCore>();

		for (Voter voter : voters) {
			if (voter.getOkw().getId().compareTo(okw.getId()) == 0) {
				VoterCore voterCore = new VoterCore(voter.getName(),
						voter.getSurname(), voter.getAddress(),
						voter.getIdentificationField());
				voterCores.add(voterCore);
			}
		}

		return voterCores;
	}

	public Map<String, ElectionData> getElectionDataToSend(Election election) {
		Map<String, ElectionData> electionsMap = new HashMap<String, ElectionData>();

		election = get(Election.class, election.getId());
		ArrayList<Voter> voters = getVoters(election);

		for (OKW_Election okw_Election : election.getOkw_elections()) {
			// if (!okw_Election.getIsSend()) { TODO: Odkomentować jak będzie w
			// GUI możliwość zmiany isSend
			OKW okw = okw_Election.getOkw();
			ElectionData electionData = new ElectionData();
			ElectionCore electionCore = new ElectionCore(election.getName(),
					election.getStartDate(), election.getEndDate());
			electionData.setElection(electionCore);
			electionData.setOkwMembers(getOKWMemberCore(okw, election));
			electionData.setVotingCards(getVotingCardCore(election));
			electionData.setVoters(getVoterCores(okw, voters));

			electionsMap.put(okw.getIdentificationField(), electionData);
			// }
		}

		logger.getLoggerInstance().log(Level.FINE, "Przygotowanie danych wyborczych do wysłania dla Election: "+election.getName());
		
		return electionsMap;
	}

	public ElectionData getElectionDataToSend(Election election, OKW okw) {
		election = get(Election.class, election.getId());
		ElectionData electionData = null;

		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		OKW_Election okw_Election = (OKW_Election) session
				.createCriteria(OKW_Election.class)
				.add(Restrictions.like("okw", okw))
				.add(Restrictions.like("election", election)).uniqueResult();
		session.getTransaction().commit();

		// if (!okw_Election.getIsSend()) { TODO: Odkomentować jak będzie w GUI
		// możliwość zmiany isSend
		ArrayList<Voter> voters = getVoters(election);
		electionData = new ElectionData();
		ElectionCore electionCore = new ElectionCore(election.getName(),
				election.getStartDate(), election.getEndDate());
		electionData.setElection(electionCore);
		electionData.setOkwMembers(getOKWMemberCore(okw, election));
		electionData.setVotingCards(getVotingCardCore(election));
		electionData.setVoters(getVoterCores(okw, voters));
		// }
		return electionData;
	}

	public void saveVotes(VotesPackageCore votesPackageCore) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		VotesPackage votesPackage = new VotesPackage(votesPackageCore.getName());
		session.save(votesPackage);
		for (VoteCore voteCore : votesPackageCore.getVoteCores()) {
			Vote vote = new Vote(voteCore.getCreatedTime());
			vote.setAfterEndTime(voteCore.getAfterEndTime());
			vote.setElectionName(voteCore.getElectionName());
			session.save(vote);
			vote.setVotesPackage(votesPackage);
			for (Long ckwVotingSubcardOption : voteCore
					.getCkwVotingSubcardOptions()) {
				VotingSubcardOption votingSubcardOption = (VotingSubcardOption) session
						.createCriteria(VotingSubcardOption.class)
						.add(Restrictions.like("id", ckwVotingSubcardOption))
						.uniqueResult();
				vote.addToVotingSubcardOption(votingSubcardOption);
				session.update(vote);
				session.update(votingSubcardOption);
			}
			logger.getLoggerInstance().log(Level.FINE, "Zapisanie głosu");
		}

		session.getTransaction().commit();
	}

	public void saveVotingCard(VotingCard votingCard) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		session.save(votingCard);
		for (VotingSubcard votingSubcard : votingCard.getVotingSubcards()) {
			session.save(votingSubcard);
			for (VotingSubcardOption votingSubcardOption : votingSubcard
					.getVotingSubcardOptions())
				session.save(votingSubcardOption);
		}

		session.getTransaction().commit();
	}

	private Timestamp getCurrentTime() {
		Calendar cal = Calendar.getInstance();
		return new Timestamp(cal.getTime().getTime());
	}

	public void addSimpleElectionExample() {
		DatabaseManager db = DatabaseManager.getInstance();

		OKW okw1 = new OKW("okw1", "id1", "a1");
		db.save(okw1);
		OKW okw2 = new OKW("okw2", "id2", "a2");
		db.save(okw2);

		OKWMember okwMember1 = new OKWMember("okwMember1", "s1", "a1", "id1");
		db.save(okwMember1);
		OKWMember okwMember2 = new OKWMember("okwMember2", "s2", "a2", "id2");
		db.save(okwMember2);
		OKWMember okwMember3 = new OKWMember("okwMember3", "s3", "a3", "id3");
		db.save(okwMember3);

		try {
			db.addOKWMemberToOKW(okwMember1, okw1);
			db.addOKWMemberToOKW(okwMember2, okw1);
			db.addOKWMemberToOKW(okwMember3, okw2);
		} catch (ConnectionBetweenObjectsException e) {
			e.printStackTrace();
		}

		Voter voter1 = new Voter("voter1", "s", "a", "id1", okw1);
		db.save(voter1);
		Voter voter2 = new Voter("voter2", "s", "a", "id2", okw1);
		db.save(voter2);
		Voter voter3 = new Voter("voter3", "s", "a", "id3", okw2);
		db.save(voter3);

		VotersList votersList = new VotersList("lista1", "opis");
		db.save(votersList);
		try {
			db.addVoterToVotersList(voter1, votersList);
			db.addVoterToVotersList(voter2, votersList);
			db.addVoterToVotersList(voter3, votersList);
		} catch (ConnectionBetweenObjectsException e) {
			e.printStackTrace();
		}

		Election election1 = new Election("Wybory tmp", getCurrentTime(),
				getCurrentTime());
		db.save(election1);
		db.addOKWToElection(okw1, election1);
		db.addVoterListToElection(votersList, election1);
		db.addNonresidentVoterToElection(voter2, election1);
		db.saveAdministratorToken("token1", okwMember1, election1);
		db.saveAdministratorToken("token11", okwMember1, election1);
		db.saveAdministratorToken("token2", okwMember2, election1);
		db.saveAdministratorToken("token3", okwMember3, election1);

		VotingCard votingCard1 = new VotingCard("votingCard1", "opis",
				election1);
		db.save(votingCard1);
		VotingSubcard votingSubcard1 = new VotingSubcard("votingSubcard1", "o",
				1, votingCard1);
		db.save(votingSubcard1);
		VotingSubcardOption votingSubcardOption1 = new VotingSubcardOption(
				"votingSubcardOption1", votingSubcard1);
		db.save(votingSubcardOption1);
		VotingSubcardOption votingSubcardOption2 = new VotingSubcardOption(
				"votingSubcardOption2", votingSubcard1);
		db.save(votingSubcardOption2);
		VotingSubcard votingSubcard2 = new VotingSubcard("votingSubcard2", "o",
				1, votingCard1);
		db.save(votingSubcard2);
		VotingSubcardOption votingSubcardOption3 = new VotingSubcardOption(
				"votingSubcardOption3", votingSubcard2);
		db.save(votingSubcardOption3);
		VotingCard votingCard2 = new VotingCard("votingCard2", "opis",
				election1);
		db.save(votingCard2);
		VotingSubcard votingSubcard3 = new VotingSubcard("votingSubcard3", "a",
				2, votingCard2);
		db.save(votingSubcard3);
		VotingSubcardOption votingSubcardOption4 = new VotingSubcardOption(
				"votingSubcardOption4", votingSubcard3);
		db.save(votingSubcardOption4);

	}

	public void addSimpleElectionExample2() {
		DatabaseManager db = DatabaseManager.getInstance();

		OKWMember okwMember1 = new OKWMember("okwMember4", "s1", "a1", "id4");
		db.save(okwMember1);

		try {
			db.addOKWMemberToOKW(okwMember1, db.getOKW("id1"));
		} catch (ConnectionBetweenObjectsException e) {
			e.printStackTrace();
		}

		Voter voter1 = new Voter("voter4", "s", "a", "id4", db.getOKW("id1"));
		db.save(voter1);

		VotersList votersList = new VotersList("lista2", "opis");
		db.save(votersList);
		try {
			db.addVoterToVotersList(voter1, votersList);
		} catch (ConnectionBetweenObjectsException e) {
			e.printStackTrace();
		}

		Election election1 = new Election("election2", null, null);
		db.save(election1);
		db.addOKWToElection(db.getOKW("id1"), election1);
		db.addVoterListToElection(votersList, election1);
		db.saveAdministratorToken("token0", okwMember1, election1);

		VotingCard votingCard1 = new VotingCard("vc1", "opis", election1);
		db.save(votingCard1);
		VotingSubcard votingSubcard1 = new VotingSubcard("vs1", "o", 1,
				votingCard1);
		db.save(votingSubcard1);
		VotingSubcardOption votingSubcardOption1 = new VotingSubcardOption(
				"vso1", votingSubcard1);
		db.save(votingSubcardOption1);
		VotingSubcardOption votingSubcardOption2 = new VotingSubcardOption(
				"vso2", votingSubcard1);
		db.save(votingSubcardOption2);
		VotingSubcard votingSubcard2 = new VotingSubcard("vs2", "o", 1,
				votingCard1);
		db.save(votingSubcard2);
		VotingSubcardOption votingSubcardOption3 = new VotingSubcardOption(
				"vso3", votingSubcard2);
		db.save(votingSubcardOption3);
		VotingCard votingCard2 = new VotingCard("vc2", "opis", election1);
		db.save(votingCard2);
		VotingSubcard votingSubcard3 = new VotingSubcard("vs3", "a", 2,
				votingCard2);
		db.save(votingSubcard3);
		VotingSubcardOption votingSubcardOption4 = new VotingSubcardOption(
				"vso4", votingSubcard3);
		db.save(votingSubcardOption4);

	}

	public static void main(String[] args) {
		DatabaseManager db = DatabaseManager.getInstance();

		db.clearDatabase(true);
//		db.addSimpleElectionExample();
		// db.addSimpleElectionExample2();

		 OKW okw = new OKW("okwsss", "id10", "ad");
		 db.save(okw);
		 db.clearDatabase(true);
		//
		// OKWMember okwMember = new OKWMember("ss", "as", "ss", "id01");
		// db.save(okwMember);
		//
		// try {
		// db.addOKWMemberToOKW(okwMember, okw);
		// } catch (ConnectionBetweenObjectsException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		//
		// System.out.println(db.okwHasOkwMember(okw, okwMember));
		//
		db.closeDatabaseSession();
	}

	public void deleteOKW(OKW okw, Boolean withVoters)
			throws OKWWithElectionException {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		okw = (OKW) session.get(OKW.class, okw.getId());
		Set<OKW_Election> okw_Elections = new HashSet<OKW_Election>(
				okw.getOkw_elections());

		for (OKW_Election okw_Election : okw_Elections) {
			if (okw_Election.getStatus() != 0)
				throw new OKWWithElectionException();
		}

		for (OKWMember okwMember : new HashSet<OKWMember>(okw.getOkwMembers())) {
			okw.removeFromOkwMember(okwMember);
			session.update(okwMember);
		}
		for (OKW_Election okw_Election : okw_Elections) {
			okw_Election.removeFromOkw(okw);
			okw_Election.removeFromElection(okw_Election.getElection());
			session.delete(okw_Election);
		}
		for (Voter voter : new HashSet<Voter>(okw.getVoters())) {
			okw.removeFromVoter(voter);
			if (withVoters)
				session.delete(voter);
			else
				session.update(voter);
		}
		Configuration configuration = okw.getConfiguration();

		if (configuration != null) {
			ConfigurationManager cm = ConfigurationManager.getInstance();
			cm.removeConfig(configuration.getIdentificationField());
			session.delete(configuration);
		}

		if (withVoters)
			logger.getLoggerInstance().log(Level.FINE, "Usunięcie OKW: {0} z głosującymi",new Object[] {okw.getIdentificationField()});
		else
			logger.getLoggerInstance().log(Level.FINE, "Usunięcie OKW: {0}",new Object[] {okw.getIdentificationField()});

		session.delete(okw);
		session.getTransaction().commit();
	}

	public void deleteOKWMember(OKWMember okwMember) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		okwMember = (OKWMember) session.get(OKWMember.class, okwMember.getId());
		for (OKW okw : okwMember.getOkws()) {
			okwMember.removeFromOkws(okw);
		}

		Set<AdministratorToken> administratorTokens = new HashSet<AdministratorToken>(
				okwMember.getAdministratorTokens());
		for (AdministratorToken administratorToken : administratorTokens) {
			administratorToken.removeFromElection(administratorToken
					.getElection());
			administratorToken.removeFromOkwmember(okwMember);
			session.delete(administratorToken);
		}

		logger.getLoggerInstance().log(Level.FINE, "Usunięcie OKWMembera: "+okwMember.getIdentificationField());

		session.delete(okwMember);

		session.getTransaction().commit();
		
	}

	public void deleteVoter(Voter voter) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		voter = (Voter) session.get(Voter.class, voter.getId());
		voter.removeFromOkw(voter.getOkw());
		Set<VotersList> votersLists = new HashSet<>(voter.getVotersLists());
		for (VotersList votersList : votersLists) {
			votersList.removeFromVoter(voter);
		}

		@SuppressWarnings("unchecked")
		ArrayList<NonresidentVoter> nonresidentVoters = (ArrayList<NonresidentVoter>) session
				.createCriteria(NonresidentVoter.class)
				.add(Restrictions.like("voter", voter)).list();
		for (NonresidentVoter nonresidentVoter : nonresidentVoters) {
			nonresidentVoter = (NonresidentVoter) session.get(
					NonresidentVoter.class, nonresidentVoter.getId());
			if (nonresidentVoter != null) {
				nonresidentVoter.removeFromElection(nonresidentVoter
						.getElection());
				session.delete(nonresidentVoter);
			}
		}

		session.delete(voter);

		session.getTransaction().commit();
	}

	public void clearDatabase(Boolean deleteConfiguration) {
		Query query;

		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		// Message
		query = session.createQuery("from Message");
		@SuppressWarnings("unchecked")
		ArrayList<Message> messages = (ArrayList<Message>) query.list();
		for (Message message : messages)
			session.delete(message);
		// State
		query = session.createQuery("from State");
		@SuppressWarnings("unchecked")
		ArrayList<State> states = (ArrayList<State>) query.list();
		for (State state : states)
			session.delete(state);
		// Voter
		query = session.createQuery("from Voter");
		@SuppressWarnings("unchecked")
		ArrayList<Voter> voters = (ArrayList<Voter>) query.list();
		for (Voter voter : voters)
			voter.removeFromOkw(voter.getOkw());
		// NonresidentVoter
		query = session.createQuery("from NonresidentVoter");
		@SuppressWarnings("unchecked")
		ArrayList<NonresidentVoter> nonresidentVoters = (ArrayList<NonresidentVoter>) query
				.list();
		for (NonresidentVoter nonresidentVoter : nonresidentVoters) {
			nonresidentVoter.removeFromElection(nonresidentVoter.getElection());
			session.delete(nonresidentVoter);
		}
		// VotersList
		query = session.createQuery("from VotersList");
		@SuppressWarnings("unchecked")
		ArrayList<VotersList> votersLists = (ArrayList<VotersList>) query
				.list();
		for (VotersList votersList : votersLists) {
			Set<Election> elections = new HashSet<Election>(
					votersList.getElections());
			for (Election election : elections)
				votersList.removeFromElection(election);
			Set<Voter> voters2 = new HashSet<Voter>(votersList.getVoters());
			for (Voter voter : voters2)
				votersList.removeFromVoter(voter);
			session.delete(votersList);
		}
		for (Voter voter : voters)
			session.delete(voter);
		// AdministratorToken
		query = session.createQuery("from AdministratorToken");
		@SuppressWarnings("unchecked")
		ArrayList<AdministratorToken> administratorTokens = (ArrayList<AdministratorToken>) query
				.list();
		for (AdministratorToken administratorToken : administratorTokens) {
			administratorToken.removeFromElection(administratorToken
					.getElection());
			administratorToken.removeFromOkwmember(administratorToken
					.getOkwmember());
			session.delete(administratorToken);
		}
		// OKWMember
		query = session.createQuery("from OKWMember");
		@SuppressWarnings("unchecked")
		ArrayList<OKWMember> okwMembers = (ArrayList<OKWMember>) query.list();
		for (OKWMember okwMember : okwMembers) {
			Set<OKW> okws = new HashSet<OKW>(okwMember.getOkws());
			for (OKW okw : okws)
				okwMember.removeFromOkws(okw);
			session.delete(okwMember);
		}
		// OKW_Election
		query = session.createQuery("from OKW_Election");
		@SuppressWarnings("unchecked")
		ArrayList<OKW_Election> okw_Elections = (ArrayList<OKW_Election>) query
				.list();
		for (OKW_Election okw_Election : okw_Elections) {
			SummaryPackage summaryPackage = okw_Election.getSummaryPackage();
			if (summaryPackage != null) {
				summaryPackage = (SummaryPackage) session.get(
						SummaryPackage.class, summaryPackage.getId());
				Set<OKWElectionResult> okwElectionResults = new HashSet<OKWElectionResult>(
						summaryPackage.getOkwElectionResults());
				for (OKWElectionResult okwElectionResult : okwElectionResults) {
					okwElectionResult.removeFromSummaryPackage(summaryPackage);
					session.delete(okwElectionResult);
				}
				summaryPackage.removeFromOKW_Election(okw_Election);
				for (Voter voter : summaryPackage.getVoters())
					summaryPackage.removeFromVoter(voter);
				session.delete(summaryPackage);
			}
			okw_Election.removeFromElection(okw_Election.getElection());
			okw_Election.removeFromOkw(okw_Election.getOkw());
			session.delete(okw_Election);
		}
		if (deleteConfiguration) {
			// OKW
			query = session.createQuery("from OKW");
			@SuppressWarnings("unchecked")
			ArrayList<OKW> okws = (ArrayList<OKW>) query.list();
			for (OKW okw : okws)
				session.delete(okw);
			// Configuration
			query = session.createQuery("from Configuration");
			@SuppressWarnings("unchecked")
			ArrayList<Configuration> configurations = (ArrayList<Configuration>) query
					.list();
			ConfigurationManager cm = ConfigurationManager.getInstance();
			for (Configuration configuration : configurations) {
				cm.removeConfig(configuration.getIdentificationField());
				session.delete(configuration);
			}
		}
		// Election
		query = session.createQuery("from Election");
		@SuppressWarnings("unchecked")
		ArrayList<Election> elections = (ArrayList<Election>) query.list();
		for (Election election : elections) {
			// VotingCard
			Set<VotingCard> votingCards = new HashSet<VotingCard>(
					election.getVotingCards());
			for (VotingCard votingCard : votingCards) {
				// VotingSubcard
				Set<VotingSubcard> votingSubcards = new HashSet<VotingSubcard>(
						votingCard.getVotingSubcards());
				for (VotingSubcard votingSubcard : votingSubcards) {
					// VotingSubcardOption
					Set<VotingSubcardOption> votingSubcardOptions = new HashSet<VotingSubcardOption>(
							votingSubcard.getVotingSubcardOptions());
					for (VotingSubcardOption votingSubcardOption : votingSubcardOptions) {
						// Vote
						Set<Vote> votes = new HashSet<Vote>(
								votingSubcardOption.getVotes());
						for (Vote vote : votes) {
							vote.removeFromVotingSubcardOption(votingSubcardOption);
							session.delete(vote);
						}
						votingSubcardOption
								.removeFromVotingSubcard(votingSubcard);
						session.delete(votingSubcardOption);
					}
					votingSubcard.removeFromVotingCard(votingCard);
					session.delete(votingSubcard);
				}
				votingCard.removeFormElection(election);
				session.delete(votingCard);
			}
			session.delete(election);
		}
		// Vote
		query = session.createQuery("from Vote");
		@SuppressWarnings("unchecked")
		ArrayList<Vote> votes = (ArrayList<Vote>) query.list();
		for (Vote vote : votes)
			session.delete(vote);
		// VotesPackage
		query = session.createQuery("from VotesPackage");
		@SuppressWarnings("unchecked")
		ArrayList<VotesPackage> votesPackages = (ArrayList<VotesPackage>) query
				.list();
		for (VotesPackage votesPackage : votesPackages)
			session.delete(votesPackage);

		session.getTransaction().commit();
		if (deleteConfiguration)
			logger.getLoggerInstance().log(Level.FINE, "Wyczyszczenie bazy danych z konfiguracją");
		else
			logger.getLoggerInstance().log(Level.FINE, "Wyczyszczenie bazy danych bez konfiguracji");
	}

	public void saveSummaryPackage(SummaryPackageCore summaryPackageCore,
			String okwIdentificationField) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		OKW okw = (OKW) session
				.createCriteria(OKW.class)
				.add(Restrictions.like("identificationField",
						okwIdentificationField)).uniqueResult();
		Election election = (Election) session
				.createCriteria(Election.class)
				.add(Restrictions.like("name",
						summaryPackageCore.getElectionName())).uniqueResult();
		OKW_Election okw_Election = (OKW_Election) session
				.createCriteria(OKW_Election.class)
				.add(Restrictions.like("okw", okw))
				.add(Restrictions.like("election", election)).uniqueResult();

		SummaryPackage summaryPackage = new SummaryPackage();
		summaryPackage.setVotesNumber(summaryPackageCore.getVotesNumber());
		summaryPackage.setProperVotesNumber(summaryPackageCore
				.getProperVotesNumber());
		summaryPackage.setActualStartDate(summaryPackageCore
				.getActualStartDate());
		summaryPackage.setActualEndDate(summaryPackageCore.getActualEndDate());

		session.save(summaryPackage);

		for (OKWElectionResultCore okwElectionResultCore : summaryPackageCore
				.getOkwElectionResults()) {
			OKWElectionResult okwElectionResult = new OKWElectionResult(
					okwElectionResultCore.getCkwVotingSubcardOption(),
					okwElectionResultCore.getVotesNumber());
			okwElectionResult.addToSummaryPackage(summaryPackage);
			session.save(okwElectionResult);
		}
		session.update(summaryPackage);

		for (String voterId : summaryPackageCore
				.getVotersIdentificationFields()) {
			Voter voter = (Voter) session.createCriteria(Voter.class)
					.add(Restrictions.like("identificationField", voterId))
					.uniqueResult();
			summaryPackage.addToVoter(voter);
			session.update(voter);
		}
		session.update(summaryPackage);

		okw_Election.setSummaryPackage(summaryPackage);
		session.update(okw_Election);
		session.getTransaction().commit();
		logger.getLoggerInstance().log(Level.FINE, "Zapisanie paczki podsumowującej dla OKW: "+okwIdentificationField);
	}

	public void checkElectionStatus(String electionName) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		Election election = (Election) session.createCriteria(Election.class)
				.add(Restrictions.like("name", electionName)).uniqueResult();

		if (election.getStatus() == 0) {
			for (OKW_Election okw_Election : election.getOkw_elections()) {
				okw_Election = (OKW_Election) session.get(OKW_Election.class,
						okw_Election.getId());
				if (okw_Election.getStatus() == 1) {
					election.setStatus(1);
					session.update(election);
					session.getTransaction().commit();
					return;
				}
			}
		} else if (election.getStatus() == 1) {
			for (OKW_Election okw_Election : election.getOkw_elections()) {
				okw_Election = (OKW_Election) session.get(OKW_Election.class,
						okw_Election.getId());
				if (okw_Election.getStatus() == 1
						|| okw_Election.getStatus() == 0) {
					session.getTransaction().commit();
					return;
				}
			}
			election.setStatus(3);
			session.update(election);
		}
		session.getTransaction().commit();
	}

	public ElectionResultPattern getElectionResult(Election election) {
		if (election.getStatus()!=3) 
			return null;
					
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		ElectionResultPattern electionRP = new ElectionResultPattern(
				election.getName(), election.getStartDate(),
				election.getEndDate());

		for (VotingCard votingCard : election.getVotingCards()) {
			votingCard = (VotingCard) session.get(VotingCard.class,
					votingCard.getId());
			VotingCardResultPattern votingCardRP = new VotingCardResultPattern(
					votingCard.getName());
			for (VotingSubcard votingSubcard : votingCard.getVotingSubcards()) {
				votingSubcard = (VotingSubcard) session.get(
						VotingSubcard.class, votingSubcard.getId());
				for (VotingSubcardOption votingSubcardOption : votingSubcard
						.getVotingSubcardOptions()) {
					votingSubcardOption = (VotingSubcardOption) session.get(
							VotingSubcardOption.class,
							votingSubcardOption.getId());
					VotingSubcardOptionResultPattern votingSubcardOptionRP = new VotingSubcardOptionResultPattern(
							votingSubcardOption.getName(),
							votingSubcard.getName(), votingSubcardOption
									.getVotes().size(),
							votingSubcardOption.getId());
					electionRP.setVotes(electionRP.getVotes()
							+ votingSubcardOption.getVotes().size());
					votingCardRP.getVotingSubcardOptions().add(
							votingSubcardOptionRP);
				}
			}
			electionRP.getVotingCards().add(votingCardRP);
		}

		for (OKW_Election okw_Election : election.getOkw_elections()) {
			OKWResultPattern okwRP;
			okw_Election = (OKW_Election) session.get(OKW_Election.class,
					okw_Election.getId());
			OKW okw = okw_Election.getOkw();
			okw = (OKW) session.get(OKW.class, okw.getId());
			SummaryPackage summaryPackage = okw_Election.getSummaryPackage();
			summaryPackage = (SummaryPackage) session.get(SummaryPackage.class,
					summaryPackage.getId());

			okwRP = new OKWResultPattern(okw.getName(), summaryPackage
					.getVoters().size(), summaryPackage.getVotesNumber(),
					summaryPackage.getProperVotesNumber(),
					summaryPackage.getActualStartDate(),
					summaryPackage.getActualEndDate(),
					summaryPackage.getAfterTimeVotesNumber());
			electionRP.setVoters(electionRP.getVoters()
					+ summaryPackage.getVoters().size());
			electionRP.setProperVotes(electionRP.getProperVotes()
					+ summaryPackage.getProperVotesNumber());
			electionRP.setAfterEndTimeVotes(electionRP.getAfterEndTimeVotes()
					+ summaryPackage.getAfterTimeVotesNumber());

			for (OKWMember okwMember : okw.getOkwMembers()) {
				okwMember = (OKWMember) session.get(OKWMember.class,
						okwMember.getId());
				OKWMemberResultPattern okwMemberRP = new OKWMemberResultPattern(
						okwMember.getName(), okwMember.getSurname());
				okwRP.getOkwMembers().add(okwMemberRP);
			}

			for (VotingCardResultPattern votingCardResultPattern : electionRP
					.getVotingCards()) {
				VotingCardResultPattern votingCardRP = new VotingCardResultPattern(
						votingCardResultPattern.getName());
				for (VotingSubcardOptionResultPattern votingSubcardOptionResultPattern : votingCardRP
						.getVotingSubcardOptions()) {
					VotingSubcardOptionResultPattern votingSubcardOptionRP = new VotingSubcardOptionResultPattern(
							votingSubcardOptionResultPattern.getName());
					OKWElectionResult okwElectionResult = (OKWElectionResult) session
							.createCriteria(OKWElectionResult.class)
							.add(Restrictions.like("summaryPackage",
									summaryPackage))
							.add(Restrictions.like("ckwVotingSubcardOption",
									votingSubcardOptionResultPattern.getId()))
							.uniqueResult();
					votingSubcardOptionRP.setVotes(okwElectionResult
							.getVotesNumber());
					votingSubcardOptionRP
							.setSubcardName(votingSubcardOptionResultPattern
									.getSubcardName());
					votingCardRP.getVotingSubcardOptions().add(
							votingSubcardOptionRP);
				}
				okwRP.getVotingCards().add(votingCardRP);
			}
			electionRP.getOkws().add(okwRP);
		}

		for (NonresidentVoter nonresidentVoter : election
				.getNonresidentVoters()) {
			nonresidentVoter = (NonresidentVoter) session.get(
					NonresidentVoter.class, nonresidentVoter.getId());
			electionRP
					.setNonresidentVoters(electionRP.getNonresidentVoters() + 1);
			if (nonresidentVoter.getVoterStatus() == 2)
				electionRP.setNonresidentVotersWithVote(electionRP
						.getNonresidentVotersWithVote() + 1);
		}

		session.getTransaction().commit();
		logger.getLoggerInstance().log(Level.FINE, "Pobranie wyników wyborów dla Election: "+election.getName());
		return electionRP;
	}

	public ElectionResultPattern getSampleElectionResult() {
		ElectionResultPattern electionRP = new ElectionResultPattern(
				"Wybory 1", getCurrentTime(), getCurrentTime());
		electionRP.setVoters(10);
		electionRP.setVotes(8);
		electionRP.setProperVotes(6);
		electionRP.setAfterEndTimeVotes(2);
		electionRP.setNonresidentVoters(2);
		electionRP.setNonresidentVotersWithVote(1);

		VotingCardResultPattern vc1 = new VotingCardResultPattern("karta1");
		electionRP.getVotingCards().add(vc1);
		VotingSubcardOptionResultPattern vsco1 = new VotingSubcardOptionResultPattern(
				"opcja1.1.1", "lista1.1", 5, null);
		vc1.getVotingSubcardOptions().add(vsco1);
		VotingSubcardOptionResultPattern vsco2 = new VotingSubcardOptionResultPattern(
				"opcja1.1.2", "lista1.1", 3, null);
		vc1.getVotingSubcardOptions().add(vsco2);
		VotingSubcardOptionResultPattern vsco3 = new VotingSubcardOptionResultPattern(
				"opcja1.1.3", "lista1.1", 1, null);
		vc1.getVotingSubcardOptions().add(vsco3);
		VotingSubcardOptionResultPattern vsco4 = new VotingSubcardOptionResultPattern(
				"opcja1.2.1", "lista1.2", 4, null);
		vc1.getVotingSubcardOptions().add(vsco4);
		VotingSubcardOptionResultPattern vsco5 = new VotingSubcardOptionResultPattern(
				"opcja1.2.2", "lista1.2", 3, null);
		vc1.getVotingSubcardOptions().add(vsco5);
		VotingCardResultPattern vc2 = new VotingCardResultPattern("karta2");
		electionRP.getVotingCards().add(vc2);
		VotingSubcardOptionResultPattern vsco6 = new VotingSubcardOptionResultPattern(
				"opcja2.1.1", "lista2.1", 2, null);
		vc2.getVotingSubcardOptions().add(vsco6);
		VotingSubcardOptionResultPattern vsco7 = new VotingSubcardOptionResultPattern(
				"opcja2.1.2", "lista2.1", 0, null);
		vc2.getVotingSubcardOptions().add(vsco7);
		VotingSubcardOptionResultPattern vsco8 = new VotingSubcardOptionResultPattern(
				"opcja2.2.1", "lista2.2", 1, null);
		vc2.getVotingSubcardOptions().add(vsco8);
		VotingSubcardOptionResultPattern vsco9 = new VotingSubcardOptionResultPattern(
				"opcja2.2.2", "lista2.2", 1, null);
		vc2.getVotingSubcardOptions().add(vsco9);

		OKWResultPattern okw1 = new OKWResultPattern("okw1", 5, 5, 3,
				getCurrentTime(), getCurrentTime(), 0);
		electionRP.getOkws().add(okw1);
		OKWMemberResultPattern okwMember1 = new OKWMemberResultPattern(
				"Wojtek1", "W1");
		okw1.getOkwMembers().add(okwMember1);
		OKWMemberResultPattern okwMember2 = new OKWMemberResultPattern(
				"Łukasz1", "S1");
		okw1.getOkwMembers().add(okwMember2);
		for (VotingCardResultPattern vcrp : electionRP.getVotingCards()) {
			VotingCardResultPattern vc = new VotingCardResultPattern(
					vcrp.getName());
			for (VotingSubcardOptionResultPattern vscorp : vcrp
					.getVotingSubcardOptions()) {
				VotingSubcardOptionResultPattern vsco = new VotingSubcardOptionResultPattern(
						vscorp.getName());
				vsco.setVotes(vscorp.getVotes());
				vsco.setSubcardName(vscorp.getSubcardName());
				vc.getVotingSubcardOptions().add(vsco);
			}
			okw1.getVotingCards().add(vc);
		}

		OKWResultPattern okw2 = new OKWResultPattern("okw2", 3, 3, 3,
				getCurrentTime(), getCurrentTime(), 2);
		electionRP.getOkws().add(okw2);
		OKWMemberResultPattern okwMember3 = new OKWMemberResultPattern(
				"Wojtek2", "W2");
		okw2.getOkwMembers().add(okwMember3);
		OKWMemberResultPattern okwMember4 = new OKWMemberResultPattern(
				"Łukasz2", "S2");
		okw2.getOkwMembers().add(okwMember4);
		for (VotingCardResultPattern vcrp : electionRP.getVotingCards()) {
			VotingCardResultPattern vc = new VotingCardResultPattern(
					vcrp.getName());
				for (VotingSubcardOptionResultPattern vscorp : vcrp
						.getVotingSubcardOptions()) {
					VotingSubcardOptionResultPattern vsco = new VotingSubcardOptionResultPattern(
							vscorp.getName());
					vsco.setVotes(vscorp.getVotes());
					vsco.setSubcardName(vscorp.getSubcardName());
					vc.getVotingSubcardOptions().add(vsco);
				}
			okw2.getVotingCards().add(vc);
		}

		return electionRP;
	}

	public Boolean okwHasOkwMember(OKW okw, OKWMember okwMember) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		OKWMember tmpOkwMember = (OKWMember) session
				.createCriteria(OKWMember.class).createAlias("okws", "o")
				.add(Restrictions.like("o.id", okw.getId())).uniqueResult();

		session.getTransaction().commit();

		if (tmpOkwMember != null)
			return true;
		else
			return false;
	}

	public Boolean voterOnVotersList(Voter voter, VotersList votersList) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		VotersList tmpVotersList = (VotersList) session
				.createCriteria(VotersList.class).createAlias("voters", "v")
				.add(Restrictions.like("v.id", voter.getId()))
				.add(Restrictions.like("id", votersList.getId()))
				.uniqueResult();

		session.getTransaction().commit();

		if (tmpVotersList != null)
			return true;
		else
			return false;
	}
}
